package middleware

import (
	"context"
	"easy-note/config"
	"easy-note/gateway/handler"
	"easy-note/gateway/utils/resp"
	"easy-note/models"
	user2 "easy-note/user/kitex_gen/user"
	"github.com/cloudwego/hertz/pkg/app"
	"github.com/hertz-contrib/jwt"
	"log"
)

var identityKey = "username"

func JWT() *jwt.HertzJWTMiddleware {
	jwtConf := config.GetConfig().JWT
	authMiddleware, err := jwt.New(&jwt.HertzJWTMiddleware{
		Key:         []byte(jwtConf.Secrete),
		IdentityKey: identityKey,
		PayloadFunc: func(data interface{}) jwt.MapClaims {
			if v, ok := data.(*models.User); ok {
				return jwt.MapClaims{
					identityKey: v.Username,
				}
			}
			return jwt.MapClaims{}
		},
		IdentityHandler: func(ctx context.Context, c *app.RequestContext) interface{} {
			claims := jwt.ExtractClaims(ctx, c)
			user, err := handler.UserClient.GetUserByUsername(ctx, &user2.ReqGetUserByUsername{Username: claims[identityKey].(string)})
			if err != nil {
				return nil
			}
			if user == nil {
				resp.BadRequestResponse(c, 6, "用户不存在")
				c.Abort()
				return nil
			}
			c.Set("user", user)
			c.Set("userId", user.GetId())
			return &user
		},
		Authenticator: func(ctx context.Context, c *app.RequestContext) (interface{}, error) {
			var loginValue struct {
				Username, Password string
			}
			if err := c.BindAndValidate(&loginValue); err != nil {
				return "", jwt.ErrMissingLoginValues
			}
			username := loginValue.Username
			password := loginValue.Password
			result, err := handler.UserClient.CheckUser(ctx, &user2.ReqCheckUser{Username: username, Password: password})
			if err != nil {
				return nil, jwt.ErrFailedAuthentication
			}
			if result.GetIsExist() {
				return &models.User{Username: username}, nil
			}

			return nil, jwt.ErrFailedAuthentication
		},
		Unauthorized: func(ctx context.Context, c *app.RequestContext, code int, message string) {
			resp.BaseResponse(c, code, code, message, nil)
		},
	})
	if err != nil {
		log.Fatalln(err)
	}
	return authMiddleware
}
